<template>
  <div class="app-container">
    <div class="ai-chat-container">
      <!-- 左侧历史对话列表 -->
      <div class="chat-sidebar" :class="{ collapsed: sidebarCollapsed }">
        <div class="sidebar-header">
          <h3 class="sidebar-title" v-if="!sidebarCollapsed">
            <i class="el-icon-chat-dot-round"></i>
            对话历史
          </h3>
          <el-button
            type="text"
            :icon="
              sidebarCollapsed ? 'el-icon-arrow-right' : 'el-icon-arrow-left'
            "
            @click="sidebarCollapsed = !sidebarCollapsed"
            class="collapse-btn"
          />
        </div>

        <div class="sidebar-content" v-if="!sidebarCollapsed">
          <!-- 新增对话按钮 -->
          <div class="new-chat-section">
            <el-button
              type="primary"
              icon="el-icon-plus"
              @click="createNewChat"
              class="new-chat-btn"
              size="small"
            >
              新建对话
            </el-button>
          </div>

          <!-- 对话列表 -->
          <div class="chat-list">
            <div
              v-for="(chat, index) in chatHistory"
              :key="chat.id"
              :class="['chat-item', { active: currentChatId === chat.id }]"
              @click="switchChat(chat.id)"
            >
              <div class="chat-item-content">
                <div class="chat-title">
                  <i class="el-icon-chat-line-round"></i>
                  {{ chat.title || `对话 ${index + 1}` }}
                </div>
                <div class="chat-preview">
                  {{ chat.preview || "暂无消息" }}
                </div>
                <div class="chat-time">{{ formatTime(chat.lastTime) }}</div>
              </div>
              <div class="chat-actions">
                <el-button
                  type="text"
                  icon="el-icon-delete"
                  size="mini"
                  @click.stop="deleteChat(chat.id)"
                  class="delete-chat-btn"
                />
              </div>
            </div>

            <div v-if="chatHistory.length === 0" class="empty-chat-list">
              <i class="el-icon-chat-dot-round"></i>
              <p>暂无对话记录</p>
              <el-button type="text" @click="createNewChat"
                >开始新对话</el-button
              >
            </div>
          </div>
        </div>
      </div>

      <!-- 主聊天区域 -->
      <div class="chat-main">
        <!-- 聊天头部 -->
        <div class="chat-header">
          <div class="header-left">
            <h3 class="chat-title">
              <i class="el-icon-s-custom"></i>
              {{ currentChatTitle }}
            </h3>
            <span class="chat-status">
              <i class="el-icon-success"></i>
              AI助手在线
            </span>
          </div>
          <div class="header-right">
            <el-select v-model="selectedModel" size="small" style="width: 140px; margin-right: 12px;">
              <el-option label="硅基流动AI" value="liudong"></el-option>
              <el-option label="ollma" value="ollma"></el-option>
            </el-select>
            <el-button
              type="text"
              icon="el-icon-download"
              @click="exportChat"
              :disabled="messages.length === 0"
              title="导出对话"
            >
              导出
            </el-button>
            <el-button
              type="danger"
              size="small"
              icon="el-icon-delete"
              @click="clearChatHistory"
              :disabled="messages.length === 0"
            >
              清空对话
            </el-button>
          </div>
        </div>

        <!-- 消息历史区域 -->
        <div class="chat-history" ref="chatHistory">
          <div
            v-for="(message, index) in messages"
            :key="index"
            :class="['message-container', message.role]"
          >
            <!-- 头像 -->
            <div class="avatar">
              <img
                v-if="message.role === 'assistant'"
                src="@/assets/ai-avatar.png"
                alt="AI"
              />
              <div v-else class="user-avatar">
                <i class="el-icon-user-solid"></i>
              </div>
            </div>

            <!-- 消息内容 -->
            <div class="message-bubble">
              <div class="message-header">
                <span class="message-role">
                  {{ message.role === "assistant" ? "AI助手" : "我" }}
                </span>
                <span class="message-time">{{
                  formatTime(message.timestamp)
                }}</span>
              </div>
              <div class="message-content">
                <pre>{{ message.content }}</pre>
              </div>
              <div class="message-actions">
                <el-tooltip content="复制" placement="top">
                  <i
                    class="el-icon-document-copy"
                    @click="copyText(message.content)"
                  ></i>
                </el-tooltip>
                <el-tooltip content="删除" placement="top">
                  <i class="el-icon-delete" @click="deleteMessage(index)"></i>
                </el-tooltip>
              </div>
            </div>
          </div>

          <!-- 加载指示器 -->
          <div v-if="loading" class="message-container assistant">
            <div class="avatar">
              <img src="@/assets/ai-avatar.png" alt="AI" />
            </div>
            <div class="message-bubble">
              <div class="typing-indicator">
                <span class="dot"></span>
                <span class="dot"></span>
                <span class="dot"></span>
              </div>
            </div>
          </div>
        </div>

        <!-- 输入区域 -->
        <div class="input-container">
          <div class="input-wrapper" @keydown="handleKeyDown">
            <el-input
              v-model="inputMessage"
              placeholder="我是您的智能办公助手，请问有什么可以帮您？"
              type="textarea"
              :autosize="{ minRows: 2, maxRows: 4 }"
              resize="none"
              :disabled="loading"
            ></el-input>
            <el-button
              type="primary"
              :class="['send-btn', { 'loading-btn': loading }]"
              @click="sendMessage"
              :disabled="!inputMessage.trim() || loading"
            >
              <i v-if="!loading" class="el-icon-s-promotion"></i>
              <span v-else class="loading-dots">
                <span class="dot">.</span><span class="dot">.</span
                ><span class="dot">.</span>
              </span>
            </el-button>
          </div>
          <div class="footer-tips">
            <span class="hint">智能办公助手 - 为您提供高效办公解决方案</span>
            <span class="shortcut">Ctrl + Enter 发送</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { getCompletion } from "@/api/ai.js";
import { generateAnswer } from "@/api/ollama";
import { mapActions } from "vuex";

export default {
  name: "ZhinengAI",
  data() {
    return {
      inputMessage: "",
      messages: [],
      loading: false,
      sidebarCollapsed: false,
      chatHistory: [],
      currentChatId: null,
      chatCounter: 0,
      selectedModel: 'liudong',
      modelOptions: [
        { label: '硅基流动AI', value: 'liudong' },
        { label: 'ollma', value: 'ollma' }
      ],
    };
  },
  computed: {
    currentChatTitle() {
      const currentChat = this.chatHistory.find(
        (chat) => chat.id === this.currentChatId
      );
      return currentChat ? currentChat.title : "新对话";
    },
  },
  mounted() {
    this.loadChatHistory();
    if (this.chatHistory.length > 0) {
      // 恢复上次的 currentChatId，如果没有则选第一个
      const savedCurrentChatId = localStorage.getItem("aiCurrentChatId");
      const chatIdToUse = this.chatHistory.find(
        (chat) => chat.id === savedCurrentChatId
      )
        ? savedCurrentChatId
        : this.chatHistory[0].id;
      this.switchChat(chatIdToUse);
    } else {
      this.createNewChat();
    }
    this.scrollToBottom();
  },
  watch: {
    messages: {
      handler(newVal) {
        this.saveCurrentChat();
        this.updateChatPreview();
      },
      deep: true,
    },
  },
  methods: {
    ...mapActions("ai", ["incrementAiCallCount"]),

    // 创建新对话
    createNewChat() {
      this.chatCounter++;
      const newChat = {
        id: `chat_${Date.now()}_${this.chatCounter}`,
        title: `新对话`,
        preview: "",
        lastTime: Date.now(),
        messages: [],
      };
      this.chatHistory.unshift(newChat);
      this.switchChat(newChat.id);
      localStorage.setItem("aiCurrentChatId", newChat.id);
      this.saveChatHistory();
    },

    // 切换对话
    switchChat(chatId) {
      this.currentChatId = chatId;
      localStorage.setItem("aiCurrentChatId", chatId);
      const chat = this.chatHistory.find((c) => c.id === chatId);
      if (chat) {
        this.messages = [...chat.messages];
        this.scrollToBottom();
      }
    },

    // 删除对话
    deleteChat(chatId) {
      this.$confirm("确定要删除这个对话吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          const index = this.chatHistory.findIndex(
            (chat) => chat.id === chatId
          );
          if (index > -1) {
            this.chatHistory.splice(index, 1);
            this.saveChatHistory();

            // 如果删除的是当前对话，切换到第一个对话或创建新对话
            if (chatId === this.currentChatId) {
              if (this.chatHistory.length > 0) {
                this.switchChat(this.chatHistory[0].id);
              } else {
                this.createNewChat();
              }
            }

            this.$message.success("对话已删除");
          }
        })
        .catch(() => {
          this.$message.info("已取消删除");
        });
    },

    // 更新对话预览
    updateChatPreview() {
      if (this.messages.length > 0) {
        const lastMessage = this.messages[this.messages.length - 1];
        const preview =
          lastMessage.content.length > 50
            ? lastMessage.content.substring(0, 50) + "..."
            : lastMessage.content;

        const chat = this.chatHistory.find((c) => c.id === this.currentChatId);
        if (chat) {
          chat.preview = preview;
          chat.lastTime = Date.now();
          this.saveChatHistory();
        }
      }
    },

    // 保存当前对话
    saveCurrentChat() {
      const chat = this.chatHistory.find((c) => c.id === this.currentChatId);
      if (chat) {
        chat.messages = [...this.messages];
        this.saveChatHistory();
      }
    },

    // 保存对话历史
    saveChatHistory() {
      localStorage.setItem("aiChatHistory", JSON.stringify(this.chatHistory));
    },

    // 加载对话历史
    loadChatHistory() {
      const saved = localStorage.getItem("aiChatHistory");
      if (saved) {
        try {
          this.chatHistory = JSON.parse(saved);
        } catch (e) {
          this.chatHistory = [];
        }
      }
    },

    async sendMessage() {
      if (!this.inputMessage.trim() || this.loading) return;

      const userMessage = {
        role: "user",
        content: this.inputMessage.trim(),
        timestamp: Date.now(),
      };

      this.messages.push(userMessage);
      this.inputMessage = "";
      this.scrollToBottom();

      // 增加AI调用计数
      this.incrementAiCallCount();

      // 显示加载状态
      this.loading = true;

      let settled = false; // 标记是否已处理结果
      // 超时Promise
      const timeoutPromise = new Promise((_, reject) =>
        setTimeout(() => reject(new Error("timeout")), 30000)
      );

      try {
        let response;
        if (this.selectedModel === 'ollma') {
          response = await Promise.race([
            (async () => {
              try {
                const resp = await generateAnswer('deepseek-r1:1.5b', userMessage.content);
                if (!settled) {
                  settled = true;
                  return { type: "ai", resp };
                }
              } catch (e) {
                if (!settled) {
                  settled = true;
                  throw e;
                }
              }
            })(),
            (async () => {
              try {
                await timeoutPromise;
              } catch (e) {
                if (!settled) {
                  settled = true;
                  throw e;
                }
              }
            })(),
          ]);
        } else {
          response = await Promise.race([
            (async () => {
              try {
                const resp = await getCompletion({
                  model: "Qwen/Qwen2.5-7B-Instruct",
                  message: userMessage.content,
                });
                if (!settled) {
                  settled = true;
                  return { type: "ai", resp };
                }
              } catch (e) {
                if (!settled) {
                  settled = true;
                  throw e;
                }
              }
            })(),
            (async () => {
              try {
                await timeoutPromise;
              } catch (e) {
                if (!settled) {
                  settled = true;
                  throw e;
                }
              }
            })(),
          ]);
        }

        // 兼容不同模型的返回格式
        let responseContent = "";
        if (response && response.type === "ai" && response.resp) {
          if (
            response.resp.result &&
            response.resp.result.output &&
            typeof response.resp.result.output.content === "string"
          ) {
            responseContent = response.resp.result.output.content.trim();
          } else if (typeof response.resp.content === "string") {
            responseContent = response.resp.content.trim();
          } else if (typeof response.resp === "string") {
            responseContent = response.resp.trim();
          }
        }
        if (responseContent) {
          // 去除ollama返回中的<think>标签及其换行符
          responseContent = responseContent
            .replace(/<think>.*?<\/think>/gs, "")
            .replace(/^\s+|\s+$/g, "");
          const aiMessage = {
            role: "assistant",
            content: responseContent,
            timestamp: Date.now(),
          };
          this.messages.push(aiMessage);
          this.scrollToBottom();
        } else {
          throw new Error("AI回复格式错误");
        }
      } catch (error) {
        let errorMsg = "";
        if (error.message === "timeout") {
          errorMsg = "AI助手正在升级中，请稍后再试~";
        } else {
          errorMsg = "AI回复失败，请重试";
        }
        this.$message.error(errorMsg);
        const errorMessage = {
          role: "assistant",
          content: errorMsg,
          timestamp: Date.now(),
        };
        this.messages.push(errorMessage);
      } finally {
        this.loading = false;
        this.scrollToBottom();
      }
    },

    scrollToBottom() {
      this.$nextTick(() => {
        this.$refs.chatHistory.scrollTop = this.$refs.chatHistory.scrollHeight;
      });
    },

    copyText(text) {
      navigator.clipboard
        .writeText(text)
        .then(() => {
          this.$message.success("已复制到剪贴板");
        })
        .catch(() => {
          this.$message.error("复制失败");
        });
    },

    clearChatHistory() {
      this.$confirm("确定要清除所有聊天记录吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.messages = [];
          this.$message.success("聊天记录已清除");
        })
        .catch(() => {
          this.$message.info("已取消清除");
        });
    },

    deleteMessage(index) {
      this.$confirm("确定要删除这条消息吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.messages.splice(index, 1);
          this.$message.success("消息已删除");
        })
        .catch(() => {
          this.$message.info("已取消删除");
        });
    },

    exportChat() {
      if (!this.messages.length) {
        this.$message.warning("暂无对话可导出");
        return;
      }

      const mdLines = this.messages.map((msg) => {
        if (msg.role === "user") {
          return `**我：** ${msg.content}`;
        } else {
          return `**AI助手：**\n${msg.content}`;
        }
      });

      const txtLines = this.messages.map((msg) => {
        if (msg.role === "user") {
          return `我: ${msg.content}`;
        } else {
          return `AI助手: ${msg.content.replace(/\n/g, " ")}`;
        }
      });

      const mdContent = mdLines.join("\n\n");
      const txtContent = txtLines.join("\n");

      this.$confirm("请选择导出格式", "导出对话", {
        confirmButtonText: "导出为Markdown",
        cancelButtonText: "导出为TXT",
        distinguishCancelAndClose: true,
        type: "info",
      })
        .then(() => {
          this.downloadFile(mdContent, `${this.currentChatTitle}.md`);
        })
        .catch((action) => {
          if (action === "cancel") {
            this.downloadFile(txtContent, `${this.currentChatTitle}.txt`);
          }
        });
    },

    downloadFile(content, filename) {
      const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = filename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      this.$message.success("导出成功");
    },

    formatTime(timestamp) {
      const date = new Date(timestamp);
      const now = new Date();
      const diff = now - date;

      if (diff < 60000) {
        return "刚刚";
      } else if (diff < 3600000) {
        return `${Math.floor(diff / 60000)}分钟前`;
      } else if (date.toDateString() === now.toDateString()) {
        return date.toLocaleTimeString("zh-CN", {
          hour: "2-digit",
          minute: "2-digit",
        });
      } else {
        return (
          date.toLocaleDateString("zh-CN") +
          " " +
          date.toLocaleTimeString("zh-CN", {
            hour: "2-digit",
            minute: "2-digit",
          })
        );
      }
    },

    handleKeyDown(e) {
      if (e.ctrlKey && e.key === "Enter") {
        this.sendMessage();
      }
    },
  },
};
</script>

<style scoped>
/* 主容器 */
.ai-chat-container {
  height: 85vh;
  margin: 20px;
  border-radius: 16px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  background: #fff;
  display: flex;
  overflow: hidden;
}

/* 左侧边栏 */
.chat-sidebar {
  width: 280px;
  background: #f8f9fa;
  border-right: 1px solid #e9ecef;
  display: flex;
  flex-direction: column;
  transition: all 0.3s ease;
}

.chat-sidebar.collapsed {
  width: 60px;
}

.sidebar-header {
  padding: 16px;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #fff;
}

.sidebar-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #333;
  display: flex;
  align-items: center;
  gap: 8px;
}

.collapse-btn {
  padding: 4px;
  font-size: 14px;
}

.sidebar-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.new-chat-section {
  padding: 16px;
  border-bottom: 1px solid #e9ecef;
}

.new-chat-btn {
  width: 100%;
  height: 40px;
  border-radius: 8px;
  font-weight: 500;
}

.chat-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
}

.chat-item {
  padding: 12px;
  margin-bottom: 8px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid transparent;
  position: relative;
}

.chat-item:hover {
  background: #e9ecef;
}

.chat-item.active {
  background: #e3f2fd;
  border-color: #2196f3;
}

.chat-item-content {
  flex: 1;
}

.chat-title {
  font-weight: 500;
  color: #333;
  margin-bottom: 4px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
}

.chat-preview {
  color: #666;
  font-size: 12px;
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-time {
  color: #999;
  font-size: 11px;
}

.chat-actions {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.chat-item:hover .chat-actions {
  opacity: 1;
}

.delete-chat-btn {
  padding: 2px;
  color: #f56c6c;
}

.empty-chat-list {
  text-align: center;
  padding: 40px 20px;
  color: #999;
}

.empty-chat-list i {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.5;
}

.empty-chat-list p {
  margin-bottom: 16px;
}

/* 主聊天区域 */
.chat-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #fff;
}

.chat-header {
  padding: 16px 24px;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #fff;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 16px;
}

.chat-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #333;
  display: flex;
  align-items: center;
  gap: 8px;
}

.chat-status {
  color: #52c41a;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.chat-history {
  flex: 1;
  padding: 24px;
  background: #fafafa;
  overflow-y: auto;
  min-height: 200px;
}

.message-container {
  display: flex;
  margin-bottom: 24px;
  gap: 12px;
}

.message-container.user {
  flex-direction: row-reverse;
}

.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f0f0f0;
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.user-avatar {
  background: #409eff;
  color: white;
  font-size: 18px;
}

.message-bubble {
  max-width: 70%;
  background: #fff;
  border-radius: 12px;
  padding: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  position: relative;
}

.message-container.user .message-bubble {
  background: #409eff;
  color: white;
}

.message-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 12px;
  color: #999;
}

.message-container.user .message-header {
  color: rgba(255, 255, 255, 0.8);
}

.message-role {
  font-weight: 500;
}

.message-content {
  line-height: 1.6;
}

.message-content pre {
  margin: 0;
  white-space: pre-wrap;
  word-wrap: break-word;
  font-family: inherit;
}

.message-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0;
  transition: opacity 0.2s ease;
  display: flex;
  gap: 8px;
}

.message-bubble:hover .message-actions {
  opacity: 1;
}

.message-actions i {
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}

.message-actions i:hover {
  background: rgba(0, 0, 0, 0.1);
}

.message-container.user .message-actions i:hover {
  background: rgba(255, 255, 255, 0.2);
}

.typing-indicator {
  display: flex;
  gap: 4px;
  padding: 8px 0;
}

.typing-indicator .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #999;
  animation: typing 1.4s infinite ease-in-out;
}

.typing-indicator .dot:nth-child(1) {
  animation-delay: -0.32s;
}
.typing-indicator .dot:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes typing {
  0%,
  80%,
  100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

.input-container {
  padding: 20px 24px;
  border-top: 1px solid #e9ecef;
  background: #fff;
}

.input-wrapper {
  display: flex;
  gap: 12px;
  align-items: flex-end;
}

.input-wrapper .el-textarea {
  flex: 1;
}

.send-btn {
  height: 40px;
  width: 80px;
  border-radius: 8px;
  font-weight: 500;
}

.loading-btn {
  background: #ccc;
  border-color: #ccc;
}

.loading-dots {
  display: flex;
  gap: 2px;
}

.loading-dots .dot {
  animation: loading 1.4s infinite ease-in-out;
}

.loading-dots .dot:nth-child(1) {
  animation-delay: -0.32s;
}
.loading-dots .dot:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes loading {
  0%,
  80%,
  100% {
    opacity: 0.3;
  }
  40% {
    opacity: 1;
  }
}

.footer-tips {
  margin-top: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: #999;
}

.hint {
  display: flex;
  align-items: center;
  gap: 4px;
}

.shortcut {
  background: #f0f0f0;
  padding: 2px 6px;
  border-radius: 4px;
  font-family: monospace;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .ai-chat-container {
    margin: 10px;
    height: 90vh;
  }

  .chat-sidebar {
    width: 240px;
  }

  .chat-sidebar.collapsed {
    width: 50px;
  }

  .message-bubble {
    max-width: 85%;
  }

  .header-right {
    gap: 8px;
  }

  .header-right .el-button {
    padding: 8px 12px;
  }
}
</style>
